package com.felhr.serialportexample.ui;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.felhr.serialportexample.R;
import com.felhr.serialportexample.utils.PrintUtils;
import com.felhr.usbserial.UsbSerialDevice;
import com.lvrenyang.io.Pos;
import com.lvrenyang.io.USBPrinting;
import com.lvrenyang.io.base.IOCallBack;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 功能: 打印界面
 * <p>
 * Author: longyg
 * Date: 2019/3/4 0004.
 * Email 1020231698@qq.com
 */
public class PrintActivity extends AppCompatActivity implements View.OnClickListener, IOCallBack {
    private TextView tvInfo;
    private Button btnConnectDevice, btnPrint;

    private ExecutorService es = Executors.newScheduledThreadPool(30);
    private Pos mPos = new Pos();
    private USBPrinting mUsb = new USBPrinting();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_print);
        initViews();

        btnConnectDevice.setOnClickListener(this);
        btnPrint.setOnClickListener(this);
        btnPrint.setEnabled(false);

        try {
            mPos.Set(mUsb);
            mUsb.SetCallBack(this);
            findSerialPortDevice();
        } catch (Exception e) {
            tvInfo.append(e.getLocalizedMessage() + "\n");
        }
    }

    void initViews() {
        tvInfo = findViewById(R.id.tvInfo);
        btnConnectDevice = findViewById(R.id.btnConnectDevice);
        btnPrint = findViewById(R.id.btnPrint);
        btnPrint.setEnabled(false);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnConnectDevice:
                submitRun(new TaskClose(mUsb));
                findSerialPortDevice();
                break;
            case R.id.btnPrint:
                btnPrint.setEnabled(false);
                submitRun(new TaskPrint(mPos));
                break;
        }
    }

    void submitRun(Runnable r) {
        if (es != null) es.submit(r);
    }

    @Override
    public void OnOpen() {
        this.runOnUiThread(() -> {
            btnPrint.setEnabled(true);
            Toast.makeText(getApplicationContext(), "打印设备连接成功", Toast.LENGTH_SHORT).show();
        });
    }

    @Override
    public void OnOpenFailed() {
        this.runOnUiThread(() -> {
            btnPrint.setEnabled(false);
            Toast.makeText(getApplicationContext(), "打印设备连接失败", Toast.LENGTH_SHORT).show();
        });
    }

    @Override
    public void OnClose() {
        this.runOnUiThread(() -> btnPrint.setEnabled(false));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        submitRun(new TaskClose(mUsb));
    }

    private void findSerialPortDevice() {
        final UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        if (mUsbManager != null) {
            HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
            if (deviceList == null || deviceList.isEmpty()) {
                Toast.makeText(getApplicationContext(), "没找到设备", Toast.LENGTH_SHORT).show();
                return;
            }

            //设备存在
            UsbDevice device;
            for (Map.Entry<String, UsbDevice> entry : deviceList.entrySet()) {
                device = entry.getValue();
                if (!TextUtils.isEmpty(device.getProductName()) && device.getProductName().contains("Printer")) {
                    tvInfo.append(device.toString() + "\n" + "设备名称: " + device.getDeviceName() + "\n" + "isSupported: " + UsbSerialDevice.isSupported(device) + "\n");
                    PendingIntent mPermissionIntent = PendingIntent
                            .getBroadcast(
                                    PrintActivity.this,
                                    0,
                                    new Intent(PrintActivity.this.getApplicationInfo().packageName), 0);
                    if (!mUsbManager.hasPermission(device)) {
                        mUsbManager.requestPermission(device, mPermissionIntent);
                        Toast.makeText(getApplicationContext(), "没有权限", Toast.LENGTH_LONG).show();
                        continue;
                    }
                    Toast.makeText(PrintActivity.this, "打印设备连接中...", Toast.LENGTH_SHORT).show();
                    es.submit(new TaskOpen(mUsb, mUsbManager, device, PrintActivity.this));
                    break;
                }
                device = null;
            }
        }
    }

    public class TaskOpen implements Runnable {
        USBPrinting usb = null;
        UsbManager usbManager = null;
        UsbDevice usbDevice = null;
        Context context = null;

        TaskOpen(USBPrinting usb, UsbManager usbManager, UsbDevice usbDevice, Context context) {
            this.usb = usb;
            this.usbManager = usbManager;
            this.usbDevice = usbDevice;
            this.context = context;
        }

        @Override
        public void run() {
            if (usb != null && usbManager != null && usbDevice != null && context != null)
                usb.Open(usbManager, usbDevice, context);
        }
    }

    public class TaskPrint implements Runnable {
        Pos pos = null;

        TaskPrint(Pos pos) {
            this.pos = pos;
        }

        @Override
        public void run() {
            if (pos == null) return;
            final int bPrintResult = PrintUtils.PrintTicket(pos);
            final boolean bIsOpened = pos.GetIO().IsOpened();
            runOnUiThread(() -> {
                tvInfo.append("bIsOpened: " + bIsOpened + ", bPrintResult: " + bPrintResult + "\n");
                btnPrint.setEnabled(bIsOpened);
                Toast.makeText(getApplicationContext(), getString(bPrintResult == 0 ? R.string.print_success : R.string.print_failed) + " " +
                        PrintUtils.ResultCodeToString(bPrintResult), Toast.LENGTH_SHORT).show();
            });
        }
    }

    public class TaskClose implements Runnable {
        USBPrinting usb = null;

        TaskClose(USBPrinting usb) {
            this.usb = usb;
        }

        @Override
        public void run() {
            if (usb != null) usb.Close();
        }
    }
}